package com.cy.shiro;

import com.cy.model.Account;
import com.cy.model.AccountRole;
import com.cy.model.Menu;
import com.cy.model.dingtalk.AccountMapDingding;
import com.google.common.collect.Lists;
import jodd.util.StringUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DingTalkLoginRealm extends AuthorizingRealm {

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof DingTalkUserToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        DingTalkUserToken token = (DingTalkUserToken) authcToken;
        if (token != null) {
            String dingUserId = token.getPrincipal();
            AccountMapDingding amd = AccountMapDingding.dao.findByDingUser(dingUserId);
            if (amd == null)
                return null;
            Account account = amd.getAccount();
            account.put("dingUserId", amd.getDingUserId());

            Set<String> permissions = new HashSet<>();
            List<AccountRole> roles = account.getRoles();
            List<String> roleCodes = new ArrayList<>(roles.size());
            for (AccountRole role : roles){
                roleCodes.add(role.getCode());
                for (Menu menu : Menu.dao.findByRole(role.getId())){
                    if (StringUtil.isNotBlank(menu.getUrl()) && menu.getUrl().lastIndexOf(".jsp") == -1){
                        permissions.add(menu.getUrl()+ ":"+ menu.getMethod());
                    }
                }
            }
            ShiroUser shiroUser = new ShiroUser(account);
            shiroUser.setRolesKey(Lists.newArrayList(permissions));
            shiroUser.setRoles(roleCodes);
            return new SimpleAuthenticationInfo(shiroUser, dingUserId, getName());
        }
        return null;
    }

}
